package ubo.master1.jeupoker.ia;

import ubo.master1.jeupoker.gui.LaCart;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Génération de carte de poker.
 */
public class GenereCarte {
    
    /** Le nombre de cartes. */
    private static final int NO_OF_CARDS = LaCart.NO_OF_RANKS * LaCart.NO_OF_SUITS;
    
    /** Les carte d'une partie. */
    private LaCart[] cards;
    
    /** Indice de le prochaine carte a traiter . */
    private int nextCardIndex = 0;
    
    private Random random = new Random();

    /**
     * Constructor.
     * 
     * Ordoner les cartes .
     */
    public GenereCarte() {
        cards = new LaCart[NO_OF_CARDS];
        int index = 0;
        for (int suit = LaCart.NO_OF_SUITS - 1; suit >= 0; suit--) {
            for (int rank = LaCart.NO_OF_RANKS - 1; rank >= 0 ; rank--) {
                cards[index++] = new LaCart(rank, suit);
            }
        }
    }
    
    /**
     * Mélanger la liste des cartes 
     */
    public void shuffle() {
        for (int oldIndex = 0; oldIndex < NO_OF_CARDS; oldIndex++) {
            int newIndex = random.nextInt(NO_OF_CARDS);
            LaCart tempCard = cards[oldIndex];
            cards[oldIndex] = cards[newIndex];
            cards[newIndex] = tempCard;
        }
        nextCardIndex = 0;
    }
    
    /**
     * réinitialiser la liste des cartes.
     * 
     */
    public void reset() {
        nextCardIndex = 0;
    }
    
    /**
     * Traiter une carte .
     *
     * @return  la carte traité 
     */
    public LaCart deal() {
        if (nextCardIndex + 1 >= NO_OF_CARDS) {
            throw new IllegalStateException("No cards left in deck");
        }
        return cards[nextCardIndex++];
    }
    
    /**
     * Traiter plusieurs carte au même temps.
     * 
     * @param noOfCards
     *            Le nombre de carte à traiter .
     * 
     * @return Les cartes.
     * 
     * @throws IllegalArgumentException
     *             Si le nombre de cartes est invalide
     * @throws IllegalStateException
     *             S'il n y'a pas de carte a traiter dans la liste.
     */
    public List<LaCart> deal(int noOfCards) {
        if (noOfCards < 1) {
            throw new IllegalArgumentException("noOfCards < 1");
        }
        if (nextCardIndex + noOfCards >= NO_OF_CARDS) {
            throw new IllegalStateException("No cards left in deck");
        }
        List<LaCart> dealtCards = new ArrayList<LaCart>();
        for (int i = 0; i < noOfCards; i++) {
            dealtCards.add(cards[nextCardIndex++]);
        }
        return dealtCards;
    }
    
    /**
     * Traiter une carte specifique.
     * 
     * @param rank
     *            Le numéro de la carte.
     * @param suit
     *            La couleur de la carte.
     * 
     * @return La carte s'il est valide , sinon null.
     * 
     * @throws IllegalStateException
     *             S'il n y a pas de carte à traiter dans la liste
     */
    public LaCart deal(int rank, int suit) {
        if (nextCardIndex + 1 >= NO_OF_CARDS) {
            throw new IllegalStateException("No cards left in deck");
        }
        LaCart card = null;
        int index = -1;
        for (int i = nextCardIndex; i < NO_OF_CARDS; i++) {
            if ((cards[i].getNumeroCarte() == rank) && (cards[i].getCouleurCarte() == suit)) {
                index = i;
                break;
            }
        }
        if (index != -1) {
            if (index != nextCardIndex) {
                LaCart nextCard = cards[nextCardIndex];
                cards[nextCardIndex] = cards[index];
                cards[index] = nextCard;
            }
            card = deal();
        }
        return card;
    }
    
    /*
     * (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (LaCart card : cards) {
            sb.append(card);
            sb.append(' ');
        }
        return sb.toString().trim();
    }
    
}
